package com.pb.service.boot.converter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.pb.infra.auth.entity.custom.LedingOutFile;
import com.pb.infra.oth.util.*;
import com.pb.service.boot.config.ExcelThread;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotReadableException;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.util.*;

/**
 *
 *自定义内容协商管理器 用来导出excel文件
 * @Author:  liaohaoyuan
 * @Date: 2021/3/11
 * @Time: 17:34:33
 */
public class MyMessageConverter<T> implements HttpMessageConverter<T> {@Override
public boolean canRead(Class<?> aClass, MediaType mediaType) {
    return false;
}

    @Override
    public boolean canWrite(Class<?> aClass, MediaType mediaType) {
        return true;
    }

    @Override
    public List<MediaType> getSupportedMediaTypes() {
        return MediaType.parseMediaTypes("application/xlsx");
    }

    @Override
    public T read(Class<? extends T> aClass, HttpInputMessage httpInputMessage) throws IOException, HttpMessageNotReadableException {
        return null;
    }

    @Override
    public void write(T t, MediaType mediaType, HttpOutputMessage httpOutputMessage) {
        OutputStream body = null;
        ByteArrayOutputStream bos =null;
        try {
            Map<String,Object> data = JSON.parseObject(JSONArray.toJSONString(t), LinkedHashMap.class);
            Map<String,Object> map=JSON.parseObject(JSONArray.toJSONString( data.get("data")),LinkedHashMap.class);
            String fileName=(String) map.get("fileName");
            fileName="".equals(fileName)?"test":fileName+".xlsx";//文件名
            String token=(String) map.get("token");
            List<List<Map<String,Object>>> data1=JSON.parseObject(JSONArray.toJSONString((JSONArray) map.get("data")), List.class);
            long dataSize=0;
            for (int i = 0; i <data1.size() ; i++) {
                JSONArray dataArr=JSON.parseObject(JSONArray.toJSONString(data1.get(i)),JSONArray.class);
                if(dataArr!=null){
                    dataSize+=dataArr.size()>0?dataArr.size():0;
                }
            }
            if (dataSize>3000){
                String serialNumber=UUID.randomUUID().toString();
                ExcelThread excelThread = new ExcelThread();
                excelThread.setMap(map);
                excelThread.setUserId(token);
                excelThread.setFileName(fileName);
                excelThread.setSerialNumber(serialNumber);
                Thread thread = new Thread(excelThread);
                thread.start();
                HttpHeaders headers=httpOutputMessage.getHeaders();
                headers.add("Pargam","no-cache");
                headers.add("Cache-Control","no-cache");
                bos = new ByteArrayOutputStream();
                LedingOutFile leadingOutFile = new LedingOutFile();
                leadingOutFile.setFileName(fileName);
                RedisUtil redisUtil = SpringContextUtil.getBean(RedisUtil.class);
                redisUtil.set(serialNumber,leadingOutFile,86400);
                body = httpOutputMessage.getBody();
                body.write(serialNumber.getBytes());
                body.close();
                return;
            }
            String[][] title=JSON.parseObject(JSONArray.toJSONString((JSONArray) map.get("title")), String[][].class);//获取列头
            if (JsonUtils.isJsonArray(title[0][0])){
                String[][][] titlename=JSON.parseObject(JSONArray.toJSONString((JSONArray) map.get("title")), String[][][].class);//获取列头
                String[][][] comments=JSON.parseObject(JSONArray.toJSONString((JSONArray) map.get("comments")), String[][][].class);//获取批注
                String[][] order=JSON.parseObject(JSONArray.toJSONString((JSONArray) map.get("order")), String[][].class);//数据序列
                String[][] dataType=JSON.parseObject(JSONArray.toJSONString((JSONArray) map.get("dataType")), String[][].class);//字段数据类型
                String[] jobBookName=JSON.parseObject(JSONArray.toJSONString((JSONArray) map.get("jobBookName")), String[].class);//工作簿名
                Map<String,Object> condition=JSON.parseObject(JSONArray.toJSONString(map.get("condition")), HashMap.class);//工作簿名
                if (title.length==0||jobBookName.length==0||map.size()==0||order.length==0){
                    throw new NullPointerException("数据格式异常");
                }
                Boolean contentMerge = map.get("contentMerge") == null?true:(Boolean)map.get("contentMerge");
                bos = new ByteArrayOutputStream();
                ExportData exportData = new ExportData(titlename,condition,jobBookName,comments,order);
                if(!contentMerge){
                    exportData.PoiWriteExcel2_To2007(data1,dataType,bos);
                }else{
                    exportData.PoiWriteExcel_To2007(data1,dataType,bos);
                }
                fileName = URLEncoder.encode(fileName, "UTF-8");
                HttpHeaders headers=httpOutputMessage.getHeaders();
                headers.setContentType(mediaType);
                if (fileName==null){
                    headers.add("Content-Disposition","attachment;filename=test.xlsx");
                }else {
                    headers.add("Content-disposition", "attachment;filename="+fileName+".xlsx;"+"filename*=utf-8''"+fileName+".xlsx");
                }
                headers.add("Pargam","no-cache");
                headers.add("Cache-Control","no-cache");
                byte[] bytes = bos.toByteArray();
                body = httpOutputMessage.getBody();
                body.write(bytes);
                body.flush();
            }else {
                String[][] comments=JSON.parseObject(JSONArray.toJSONString((JSONArray) map.get("comments")), String[][].class);//获取批注
                String[][] order=JSON.parseObject(JSONArray.toJSONString((JSONArray) map.get("order")), String[][].class);//数据序列
                String[][] dataType=JSON.parseObject(JSONArray.toJSONString((JSONArray) map.get("dataType")), String[][].class);//字段数据类型
                String[] jobBookName=JSON.parseObject(JSONArray.toJSONString((JSONArray) map.get("jobBookName")), String[].class);//工作簿名

                if (title.length==0||jobBookName.length==0||map.size()==0||order.length==0){
                    throw new NullPointerException("数据格式异常");
                }
                bos = new ByteArrayOutputStream();
                ExportData exportData = new ExportData(title,jobBookName,comments);
                exportData.PoiWriteExcel_To2007(data1,order,dataType,bos);
                fileName = URLEncoder.encode(fileName, "UTF-8");
                HttpHeaders headers=httpOutputMessage.getHeaders();
                headers.setContentType(mediaType);
                if (fileName==null){
                    headers.add("Content-Disposition","attachment;filename=test.xlsx");
                }else {
                    headers.add("Content-disposition", "attachment;filename="+fileName+".xlsx;"+"filename*=utf-8''"+fileName+".xlsx");
                }
                headers.add("Pargam","no-cache");
                headers.add("Cache-Control","no-cache");
                byte[] bytes = bos.toByteArray();
                body = httpOutputMessage.getBody();
                body.write(bytes);
                body.flush();
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try {
                if(bos!=null){
                    bos.close();
                }
                if (body!=null){
                    body.close();
                }
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    }
}
